package com.yuandian.business.monitor.service.impl;

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuandian.api.business_monitor.entity.E2eStudyTask;
import com.yuandian.api.business_monitor.po.E2eStudyCollect;
import com.yuandian.api.business_monitor.po.E2eStudyParam;
import com.yuandian.api.business_monitor.po.OriSample;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.business.monitor.mapper.E2eStudyTaskMapper;
import com.yuandian.business.monitor.service.IE2eStudyTaskService;
import com.yuandian.utils.IpUtils;
import com.yuandian.utils.PageDataInfo;
import com.yuandian.utils.StringUtils;
import com.yuandian.utils.poi.ExcelUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * 说明：端到端学习任务service实现
 * @Author zfsn
 * @Date 2023/7/12 14:18
 */
@Service
public class E2eStudyTaskServiceImpl extends ServiceImpl<E2eStudyTaskMapper, E2eStudyTask>
        implements IE2eStudyTaskService {

    @Autowired
    private E2eStudyTaskMapper e2eStudyTaskMapper;

    /**
     * 分页查询端到端学习任务列表
     * @param param 端到端学习请求参数
     * @return 通用返回结果
     */

    @Override
    public R page(E2eStudyParam param) {
        Page<E2eStudyTask> page = new Page<>(param.getPageNum(), param.getPageSize());
        if (StringUtils.isEmpty(param.getOrderByColumn())) {
            page.addOrder(OrderItem.desc("id"));
        } else if ("asc".equals(param.getIsAsc())) {
            page.addOrder(OrderItem.asc(StringUtils.toUnderScoreCase(param.getOrderByColumn())));
        } else if ("desc".equals(param.getIsAsc())) {
            page.addOrder(OrderItem.desc(StringUtils.toUnderScoreCase(param.getOrderByColumn())));
        }
        Page<E2eStudyTask> pages = lambdaQuery().eq(param.getSystemId() != null, E2eStudyTask::getSystemId, param.getSystemId())
                .eq(StringUtils.isNotBlank(param.getBusinessCode()), E2eStudyTask::getBusinessCode, param.getBusinessCode())
                .eq(StringUtils.isNotBlank(param.getStepCode()), E2eStudyTask::getStepCode, param.getStepCode())
                .ge(StringUtils.isNotBlank(param.getStartTime()), E2eStudyTask::getStartTime, param.getStartTime())
                .le(StringUtils.isNotBlank(param.getEndTime()), E2eStudyTask::getStartTime, param.getEndTime())
                .page(page);
        return R.ok(new PageDataInfo(page, pages.getRecords()));
    }

    /**
     * 下载样本数据
     * @param param 端到端学习请求参数
     * @param response 响应上下文
     */

    @Override
    public void downloadSample(E2eStudyParam param, HttpServletResponse response) throws IOException {
        List<Long> oriWebIdList = new ArrayList<>();
        List<Long> oriMidIdList = new ArrayList<>();
        List<Long> oriDbIdList = new ArrayList<>();
        String oriIds = param.getOriIds();
        String[] oriStrings = oriIds.split("\n");
        Map<Long, Integer> idMap = new HashMap<>();
        for (String oriString : oriStrings) {
            if (StringUtils.isBlank(oriString)) {
                continue;
            }
            String[] info = oriString.split(":");
            String oriStr = info[1];
            Integer segmentId = Integer.parseInt(info[0]);
            Long oriId = Long.parseLong(oriStr.split("\\(")[0]);
            idMap.put(oriId, segmentId);
            if (oriStr.contains("ORI_WEB")) {
                oriWebIdList.add(oriId);
            } else if (oriStr.contains("ORI_MID")) {
                oriMidIdList.add(oriId);
            } else if (oriStr.contains("ORI_DB")) {
                oriDbIdList.add(oriId);
            }
        }
        List<OriSample> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(oriWebIdList)) {
            list.addAll(e2eStudyTaskMapper.queryOri(1, oriWebIdList));
        }
        if (!CollectionUtils.isEmpty(oriMidIdList)) {
            list.addAll(e2eStudyTaskMapper.queryOri(2, oriMidIdList));
        }
        if (!CollectionUtils.isEmpty(oriDbIdList)) {
            list.addAll(e2eStudyTaskMapper.queryOri(3, oriDbIdList));
        }
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (OriSample oriSample : list) {
            oriSample.setSegmentId(idMap.get(oriSample.getId()));
            oriSample.setRequestIpStr(IpUtils.iplongToIp(oriSample.getRequestIpLong()));
            oriSample.setResponseIpStr(IpUtils.iplongToIp(oriSample.getResponseIpLong()));
        }
        String formTitleName = "原始数据样本";
        List<List<String>> headList = new ArrayList<>();
        List<String> titleList = Arrays.asList("id", "数据类型", "所属网端id", "业务服务资源编码", "请求ip", "请求端口",
                "响应ip", "响应端口", "服务器响应开始时间", "服务器响应结束时间", "专属指标", "请求原始样包", "响应原始样包",
                "解密后的请求原始样包", "解密后的响应原始样包");
        titleList.forEach(s -> {
            List<String> childHeadList = new ArrayList<>();
            childHeadList.add(formTitleName);
            childHeadList.add(s);
            headList.add(childHeadList);
        });
        ExcelUtil.writeExcel(OriSample.class, formTitleName, "原始数据样本列表", list, headList, response);
    }

    /**
     * 汇总查询
     * @param param 端到端学习请求参数
     * @return 通用返回结果
     */

    @Override
    public R collect(E2eStudyParam param) {
        List<E2eStudyCollect> list = e2eStudyTaskMapper.collect(param);
        for (E2eStudyCollect e2eStudyCollect : list) {
            if (e2eStudyCollect.getBeforeResourceCode().equals(param.getStepCode())) {
                e2eStudyCollect.setStepCode(param.getStepCode());
            }
        }
        return R.ok(list);
    }

    /**
     * 同步配置给步骤端到端学习
     * @param list 端到端学习汇总对象集合
     * @return 通用返回结果
     */
    @Override
    public R sync(List<E2eStudyCollect> list) {
        int syncCount = 0;
        int existCount = 0;
        for (E2eStudyCollect e2eStudyCollect : list) {
            int count = e2eStudyTaskMapper.queryE2eConfigExist(e2eStudyCollect);
            if (count > 0) {
                existCount++;
                continue;
            }
            e2eStudyTaskMapper.sync(e2eStudyCollect);
            syncCount++;
        }
        return R.ok("共 " + list.size() + " 条配置需要同步，" + syncCount
                + " 条同步完成，" + existCount + " 条配置已经存在无需同步");
    }
}
